#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "buffer.h"

int buffer_create(struct buffer_st *buffer, unsigned long size, int fd) {
	buffer -> write_offset = 0;
	buffer -> size = size;
	buffer -> fd = fd;
	buffer -> address = (char*)calloc(buffer -> size, sizeof(char));

	if ((buffer -> address) == NULL)
		return -1;
	return 1;
}

void buffer_free(struct buffer_st *buffer) { //call this function before
	free(buffer -> address);						//destroying the buffer
}

void buffer_clear(struct buffer_st *buffer) {
	buffer -> write_offset = 0;
}

unsigned long buffer_count_size(struct buffer_st *buffer) {
	return buffer -> write_offset;
}

unsigned long buffer_count_free_size(struct buffer_st *buffer) {
	return buffer -> size - buffer_count_size(buffer);
}

void buffer_flush(struct buffer_st *buffer) {
	write(buffer -> fd, (char*)(buffer -> address), buffer -> write_offset);
	buffer_clear(buffer);
}

int buffer_overflow(struct buffer_st *buffer, unsigned long offset) {
	if ((offset + buffer -> write_offset) >= buffer -> size) {
		return -1;
	} else {
		return 1;	//space is enough
	}
}

int buffer_write_message(struct buffer_st *buffer, char *message, int length) {
	if (length > (buffer -> size + 1)) {
		perror("Can't write message(it's too long) to log file. Writing straight to file.");
		write(buffer -> fd, message, length);
		return -1;
	}
	if (buffer_overflow(buffer, length + 1)) {		//another byte is '\n' for
		strncpy(&(((char*)(buffer->address))[buffer -> write_offset]), message, length);
		buffer -> write_offset += length;
		
		strncpy(&(((char*)(buffer->address))[buffer -> write_offset]), "\n", 1);
		(buffer -> write_offset)++;
		return 1;
	} else {
		buffer_flush(buffer);
		buffer_write_message(buffer, message, length);
	}
	return 1;
}
